/**
 * 作者:hanbo
 * 日期:2018/11/1915:41
 * 描述:TMS地图图层
 */
import {Layer} from "./Layer";
import {EXTENDS_3857} from "../core/Constant";
import {Rectangle} from "../geometry/Rectangle";
import {DownImage} from "../tool/DownImage";

export class TMSLayer extends Layer {
    /**
     * 构造器
     * @param url [string] TMS地址
     * @param type [number] TMS地图类型，0谷歌TMS,1标准TMS
     */
    constructor(url, type) {
        super();
        this.url = url;
        this.type = type;
        this.tiles=[];
    }

    /**
     * 根据地图范围绘制
     * @param mapRender {MapRender} 渲染器
     * @param extend {Rectangle} 坐标范围
     * @param level {Number} 地图等级
     * @param layerAmount {number} 图层数量
     * @param layerIndex {number} 图层索引
     * @override
     */
    draw(mapRender, extend,level,layerAmount,layerIndex) {
        let coordAndBox = TMSLayer.getTMSCoordAndBox(extend, level, this.type);
        console.log("切片数量"+coordAndBox.length);
        const uuid=this.uuid;
        for (let i = 0; i < coordAndBox.length; i++) {
            let tmsBox = coordAndBox[i];
            let currentUrl = TMSLayer.getCurrentUrl(this.url, tmsBox.x, tmsBox.y, tmsBox.z);
            DownImage.downImage(currentUrl, function (image) {
                mapRender.drawImageLoad(image, tmsBox.tileBox,uuid,layerIndex/layerAmount);
            })
        }
    }

    /**
     * 删除新刷新的无用切片
     * @param boundingBox {Rectangle} 新刷新地图范围
     */
    removeUseless(boundingBox){
      let length=this.tiles.length;
        for (let i = length-1; i >=0 ; i++) {
            if(Rectangle.isIntersect(this.tiles[i].tileBox,boundingBox)){
                this.tiles.splice(i,1);
            }
        }
    }

    /**
     * 根据等级和坐标范围计算包含瓦片坐标
     * @param boundingBox [Rectangle]  坐标范围
     * @param level [number] 地图等级
     * @param type TMS规则类型
     */
    static getTMSCoordAndBox(boundingBox, level, type) {
        let array = [];
        let tile_size = EXTENDS_3857 / Math.pow(2, level - 1);//当前等级瓦片坐标宽度（宽高相等）
        let x1 = Math.ceil((boundingBox.xMin + EXTENDS_3857) / tile_size) - 1;//起始X,减1是因为从0开始
        let x2 = Math.ceil((boundingBox.xMax + EXTENDS_3857) / tile_size) - 1;//终止X
        let y1 = 0, y2 = 0;


        switch (type) {
            case 0:
                //谷歌地图TMSy值计算
                y1 = Math.ceil((EXTENDS_3857 - boundingBox.yMax) / tile_size) - 1;//起始y
                y2 = Math.ceil((EXTENDS_3857 - boundingBox.yMin) / tile_size) - 1;//终止y
                break;
            case 1:
                //标准TMSy值计算
                y1 = Math.ceil((boundingBox.yMin + EXTENDS_3857) / tile_size) - 1;//起始y
                y2 = Math.ceil((boundingBox.yMax + EXTENDS_3857) / tile_size) - 1;//终止y
                break;
            default:
                break;
        }

        //防止计算产生负值
        if (x1 < 0) {
            x1 = 0;
        }
        if (x2 < 0) {
            x2 = 0;
        }
        if (y1 < 0) {
            y1 = 0;
        }
        if (y2 < 0) {
            y2 = 0;
        }

        for (let j = x1; j <= x2; j++) {
            for (let k = y1; k <= y2; k++) {

                let xMin = (j) * tile_size - EXTENDS_3857;
                let xMax = xMin + tile_size;
                let yMin = 0, yMax = 0;
                switch (type) {
                    case 0:
                        //谷歌地图TMSy值计算
                        yMax = EXTENDS_3857 - k * tile_size;//起始y
                        yMin = yMax - tile_size;//终止y
                        break;
                    case 1:
                        //标准TMSy值计算
                        yMin = k * tile_size - EXTENDS_3857;//起始y
                        yMax = yMin + tile_size;//终止y
                        break;
                    default:
                        break;
                }
                let tileBox = new Rectangle(xMin, yMin, xMax, yMax);
                array.push({
                    x: j,
                    y: k,
                    z: level,
                    tileBox: tileBox
                });
            }
        }

        return array;
    }

    /**
     * 根据xyz获取瓦片url地址
     * @param url [string] TMS服务地址
     * @param x [number] 瓦片x坐标
     * @param y [number] 瓦片y坐标
     * @param z [number] 瓦片z坐标
     */
    static getCurrentUrl(url, x, y, z) {
        //需要在以后改进正则，匹配大小写
        let result = url.replace("{x}", x);
        result = result.replace("{y}", y);
        result = result.replace("{z}", z);
        return result;
    }
}